{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Tce3stUlHN0L"
      },
      "source": [
        "##### Copyright 2019 The TensorFlow IO Authors."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "cellView": "form",
        "id": "tuOe1ymfHZPu"
      },
      "outputs": [],
      "source": [
        "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "# https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "qFdPvlXBOdUN"
      },
      "source": [
        "# 医療画像処理向けに DICOM ファイルをデコードする"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "MfBg1C5NB3X0"
      },
      "source": [
        "<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
        "  <td><a target=\"_blank\" href=\"https://www.tensorflow.org/io/tutorials/dicom\"><img src=\"https://www.tensorflow.org/images/tf_logo_32px.png\">View on TensorFlow.org</a></td>\n",
        "  <td><a target=\"_blank\" href=\"https://colab.research.google.com/github/tensorflow/docs-l10n/blob/master/site/ja/io/tutorials/dicom.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\"> Google Colab で実行</a></td>\n",
        "  <td><a target=\"_blank\" href=\"https://github.com/tensorflow/docs-l10n/blob/master/site/ja/io/tutorials/dicom.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\">View source on GitHub</a></td>\n",
        "      <td><a href=\"https://storage.googleapis.com/tensorflow_docs/docs-l10n/site/ja/io/tutorials/dicom.ipynb\"><img src=\"https://www.tensorflow.org/images/download_logo_32px.png\">Download notebook</a></td>\n",
        "</table>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "xHxb-dlhMIzW"
      },
      "source": [
        "## 概要\n",
        "\n",
        "このチュートリアルでは、TensorFlow IO で `tfio.image.decode_dicom_image` を使用し、TensorFlow で DICOM ファイルをデコードする方法を説明します。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "MUXex9ctTuDB"
      },
      "source": [
        "## セットアップと使用方法"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "4YsfgDMZW5g6"
      },
      "source": [
        "#### DICOM 画像のダウンロード\n",
        "\n",
        "このチュートリアルでは、[NIH Chest X-ray データセット](https://cloud.google.com/healthcare/docs/resources/public-datasets/nih-chest)の DICOM 画像を使用します。\n",
        "\n",
        "NIH Chest X-ray データセットには、100,000 件の匿名化された胸部レントゲン画像が PNG 形式で含まれています。NIH Clinical Center が提供しているデータセットで、[こちらのリンク](https://nihcc.app.box.com/v/ChestXray-NIHCC)からダウンロードできます。\n",
        "\n",
        "Google Cloud でも、DICOM バージョンの画像が提供されています。[Cloud Storage](https://cloud.google.com/healthcare/docs/resources/public-datasets/nih-chest) で入手可能です。\n",
        "\n",
        "このチュートリアルでは、[GitHub リポジトリ](https://github.com/tensorflow/io/raw/master/docs/tutorials/dicom/dicom_00000001_000.dcm)より、データセットのサンプルファイルをダウンロードします。\n",
        "\n",
        "注意: データセットの詳細については、次のリファレンスをご覧ください。\n",
        "\n",
        "- Xiaosong Wang, Yifan Peng, Le Lu, Zhiyong Lu, Mohammadhadi Bagheri, Ronald Summers, ChestX-ray8: Hospital-scale Chest X-ray Database and Benchmarks on Weakly-Supervised Classification and Localization of Common Thorax Diseases, IEEE CVPR, pp. 3462-3471, 2017\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "Tu01THzWcE-J"
      },
      "outputs": [],
      "source": [
        "!curl -OL https://github.com/tensorflow/io/raw/master/docs/tutorials/dicom/dicom_00000001_000.dcm\n",
        "!ls -l dicom_00000001_000.dcm"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "upgCc3gXybsA"
      },
      "source": [
        "### 必要なパッケージをインストールし、ランタイムを再起動する"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "NwL3fEMQuZrk"
      },
      "outputs": [],
      "source": [
        "try:\n",
        "  # Use the Colab's preinstalled TensorFlow 2.x\n",
        "  %tensorflow_version 2.x \n",
        "except:\n",
        "  pass"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "uUDYyMZRfkX4"
      },
      "outputs": [],
      "source": [
        "!pip install tensorflow-io"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "yZmI7l_GykcW"
      },
      "source": [
        "### DICOM 画像をデコードする"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "YUj0878jPyz7"
      },
      "outputs": [],
      "source": [
        "import matplotlib.pyplot as plt\n",
        "import numpy as np\n",
        "\n",
        "import tensorflow as tf"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "zK7IEukfuUuF"
      },
      "outputs": [],
      "source": [
        "import tensorflow_io as tfio\n",
        "\n",
        "image_bytes = tf.io.read_file('dicom_00000001_000.dcm')\n",
        "\n",
        "image = tfio.image.decode_dicom_image(image_bytes, dtype=tf.uint16)\n",
        "\n",
        "skipped = tfio.image.decode_dicom_image(image_bytes, on_error='skip', dtype=tf.uint8)\n",
        "\n",
        "lossy_image = tfio.image.decode_dicom_image(image_bytes, scale='auto', on_error='lossy', dtype=tf.uint8)\n",
        "\n",
        "\n",
        "fig, axes = plt.subplots(1,2, figsize=(10,10))\n",
        "axes[0].imshow(np.squeeze(image.numpy()), cmap='gray')\n",
        "axes[0].set_title('image')\n",
        "axes[1].imshow(np.squeeze(lossy_image.numpy()), cmap='gray')\n",
        "axes[1].set_title('lossy image');"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "WodUv8O1VKmr"
      },
      "source": [
        "## ドキュメント\n",
        "\n",
        "このパッケージには、`DCMTK` 関数をラッピングする 2 つの演算があります。`decode_dicom_image` はDICOM ファイルのピクセルデータをデコードし、`decode_dicom_data` はタグ情報をデコードします。`tags` には `tags.PatientsName` などの有用な DICOM タグが含まれます。タグ表記は、[`pydicom`](https://pydicom.github.io/) dicom パッケージから借りだされたものです。\n",
        "\n",
        "### DICOM 画像データを取得する\n",
        "\n",
        "```python\n",
        "io.dicom.decode_dicom_image(     contents,     color_dim=False,     on_error='skip',     scale='preserve',     dtype=tf.uint16,     name=None )\n",
        "```\n",
        "\n",
        "- **`contents`**: 文字列型のテンソルです。0 次元。バイト文字列でエンコードされた DICOM ファイルです。\n",
        "- **`color_dim`**: オプションの `bool` です。デフォルトは `False` です。`True` の場合、3 つ目のチャンネルが 3 次元テンソルを形成するすべての画像にアペンドされます。1024 x 1024 グレースケール画像は 1024 x 1024 x 1 となります。\n",
        "- **`on_error`**: デフォルトは `skip` です。この属性は、画像を開く際にエラーとなった場合、または出力型がすべての可能な入力値に対応できない場合の動作を確立します。たとえば、ユーザーが出力 dtype を `tf.uint8` に設定しているが、dicom 画像は `tf.uint16` 型を保存する場合などが該当します。`strict` はエラーをスローします。`skip` は 1 次元の空のテンソルを返します。`lossy` は、`scale` 属性経由で値をスケールしながら演算を続けます。\n",
        "- **`scale`**:  デフォルトは `preserve` です。この属性は、入力値のスケールにどのように対処するかを指定します。`auto` は、入力値を自動スケールしますが、出力型が整数である場合、`auto` は、最大出力スケールを使用します。たとえば、[0, 255] の値を格納する `uint8` は、[0,65535] の `uint16` を満たすまで直線に伸ばされ、出力が浮動小数である場合、`auto` は [0,1] にスケールします。`preserve` は値をそのまま保持し、最大可能出力より大きな入力値は切り取られます。\n",
        "- **`dtype`**: オプションの `tf.DType` で、`tf.uint8, tf.uint16, tf.uint32, tf.uint64, tf.float16, tf.float32, tf.float64` から指定されます。デフォルトは `tf.uint16` です。\n",
        "- **`name`**: 演算の名前です（オプション）。\n",
        "\n",
        "**戻り値**: `dtype` 型の `Tensor`で、形状は DICOM ファイルによって決定されます。\n",
        "\n",
        "### DICOM タグデータを取得する\n",
        "\n",
        "```python\n",
        "io.dicom.decode_dicom_data(     contents,     tags=None,     name=None )\n",
        "```\n",
        "\n",
        "- **`contents`**: 文字列型のテンソルです。0 次元。バイト文字列でエンコードされた DICOM ファイルです。\n",
        "- **`tags`**: 任意の次元の `tf.uint32` 型のテンソルです。`uint32` の数値は DICOM タグに直接マッピングされます。\n",
        "- **`name`**: 演算の名前です（オプション）。\n",
        "\n",
        "**戻り値**: `tf.string` 型の `Tensor` で、`tags` と同じ形状です。dicom タグが文字列のリストである場合、1 つの文字列に結合され、二重バックスラッシュ `\\` で区切られます。タグが数値のリストである場合には [DCMTK](https://support.dcmtk.org/docs/) にバグがあり、第 0 要素のみが文字列として返されます。\n",
        "\n",
        "### Bibtex\n",
        "\n",
        "このパッケージが役立った場合は、どうぞ以下のように引用してください。\n",
        "\n",
        "```\n",
        "@misc{marcelo_lerendegui_2019_3337331,   author       = {Marcelo Lerendegui and                   Ouwen Huang},   title        = {Tensorflow Dicom Decoder},   month        = jul,   year         = 2019,   doi          = {10.5281/zenodo.3337331},   url          = {https://doi.org/10.5281/zenodo.3337331} }\n",
        "```\n",
        "\n",
        "### ライセンス情報\n",
        "\n",
        "Copyright 2019 Marcelo Lerendegui, Ouwen Huang, Gradient Health Inc.\n",
        "\n",
        "Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n",
        "\n",
        "http://www.apache.org/licenses/LICENSE-2.0\n",
        "\n",
        "Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License."
      ]
    }
  ],
  "metadata": {
    "colab": {
      "collapsed_sections": [
        "Tce3stUlHN0L"
      ],
      "name": "dicom.ipynb",
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
